// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <div>
    <a-affix v-if="this.$store.getters.shutdownTriggered" >
      <a-alert :message="$t('message.shutdown.triggered')" type="error" banner :showIcon="false" class="shutdownHeader" />
    </a-affix>
    <a-layout class="layout" :class="[device]">
      <a-affix style="z-index: 200" :offsetTop="this.$store.getters.shutdownTriggered ? 25 : 0">
        <template v-if="isSideMenu()">
          <a-drawer
            v-if="isMobile()"
            :wrapClassName="'drawer-sider ' + navTheme"
            :closable="false"
            :visible="collapsed"
            placement="left"
            @close="() => this.collapsed = false"
          >
            <side-menu
              :menus="menus"
              :theme="navTheme"
              :collapsed="false"
              :collapsible="true"
              mode="inline"
              @menuSelect="menuSelect"></side-menu>
          </a-drawer>
          <side-menu
            v-else
            mode="inline"
            :menus="menus"
            :theme="navTheme"
            :collapsed="collapsed"
            :collapsible="true"></side-menu>
        </template>
        <template v-else>
          <a-drawer
            v-if="isMobile()"
            :wrapClassName="'drawer-sider ' + navTheme"
            placement="left"
            @close="() => this.collapsed = false"
            :closable="false"
            :visible="collapsed"
          >
            <side-menu
              :menus="menus"
              :theme="navTheme"
              :collapsed="false"
              :collapsible="true"
              mode="inline"
              @menuSelect="menuSelect"></side-menu>
          </a-drawer>
        </template>

        <drawer :visible="showSetting" placement="right" v-if="isAdmin && (isDevelopmentMode || allowSettingTheme)">
          <template #handler>
            <a-button type="primary" size="large">
              <close-outlined v-if="showSetting" />
              <setting-outlined v-else />
            </a-button>
          </template>
          <template #drawer>
            <setting :visible="showSetting" />
          </template>
        </drawer>

      </a-affix>

      <a-layout :class="[layoutMode, `content-width-${contentWidth}`]" :style="{ paddingLeft: contentPaddingLeft, minHeight: '100vh' }">
        <!-- layout header -->
        <a-affix style="z-index: 100">
          <global-header
            :style="this.$store.getters.shutdownTriggered ? 'margin-top: 25px;' : null"
            :mode="layoutMode"
            :menus="menus"
            :theme="navTheme"
            :collapsed="collapsed"
            :device="device"
            @toggle="toggle"
          />
        </a-affix>

        <a-button
          v-if="showClear"
          type="default"
          size="small"
          class="button-clear-notification"
          @click="onClearNotification">{{ $t('label.clear.notification') }}</a-button>

        <!-- layout content -->
        <a-layout-content
        class="layout-content"
        :class="{'is-header-fixed': fixedHeader}">
          <slot></slot>
        </a-layout-content>

        <!-- layout footer -->
        <a-layout-footer style="padding: 0">
          <global-footer />
        </a-layout-footer>
      </a-layout>
    </a-layout>
  </div>
</template>

<script>
import SideMenu from '@/components/menu/SideMenu'
import GlobalHeader from '@/components/page/GlobalHeader'
import GlobalFooter from '@/components/page/GlobalFooter'
import { triggerWindowResizeEvent } from '@/utils/util'
import { mapState, mapActions } from 'vuex'
import { mixin, mixinDevice } from '@/utils/mixin.js'
import { isAdmin } from '@/role'
import { api } from '@/api'
import Drawer from '@/components/widgets/Drawer'
import Setting from '@/components/view/Setting.vue'

export default {
  name: 'GlobalLayout',
  components: {
    SideMenu,
    GlobalHeader,
    GlobalFooter,
    Drawer,
    Setting
  },
  mixins: [mixin, mixinDevice],
  data () {
    return {
      collapsed: false,
      menus: [],
      showSetting: false,
      showClear: false
    }
  },
  computed: {
    ...mapState({
      mainMenu: state => state.permission.addRouters
    }),
    isAdmin () {
      return isAdmin()
    },
    isDevelopmentMode () {
      return process.env.NODE_ENV === 'development'
    },
    allowSettingTheme () {
      return this.$config.allowSettingTheme
    },
    contentPaddingLeft () {
      if (!this.fixSidebar || this.isMobile()) {
        return '0'
      }
      if (this.sidebarOpened) {
        return '256px'
      }
      return '80px'
    }
  },
  watch: {
    sidebarOpened (val) {
      this.collapsed = !val
    },
    mainMenu (newMenu) {
      this.menus = newMenu.find((item) => item.path === '/').children
    },
    '$store.getters.darkMode' (darkMode) {
      if (darkMode) {
        document.body.classList.add('dark-mode')
      } else {
        document.body.classList.remove('dark-mode')
      }
    },
    '$store.getters.countNotify' (countNotify) {
      this.showClear = false
      if (countNotify && countNotify > 0) {
        this.showClear = true
      }
    }
  },
  provide: function () {
    return {
      parentToggleSetting: this.toggleSetting
    }
  },
  created () {
    this.menus = this.mainMenu.find((item) => item.path === '/').children
    this.collapsed = !this.sidebarOpened
    if ('readyForShutdown' in this.$store.getters.apis) {
      const readyForShutdownPollingJob = setInterval(this.checkShutdown, 5000)
      this.$store.commit('SET_READY_FOR_SHUTDOWN_POLLING_JOB', readyForShutdownPollingJob)
    }
  },
  mounted () {
    const layoutMode = this.$config.theme['@layout-mode'] || 'light'
    this.$store.dispatch('SetDarkMode', (layoutMode === 'dark'))
    if (layoutMode === 'dark') {
      document.body.classList.add('dark-mode')
    }
    const userAgent = navigator.userAgent
    if (userAgent.indexOf('Edge') > -1) {
      this.$nextTick(() => {
        this.collapsed = !this.collapsed
        setTimeout(() => {
          this.collapsed = !this.collapsed
        }, 16)
      })
    }
    const countNotify = this.$store.getters.countNotify
    this.showClear = false
    if (countNotify && countNotify > 0) {
      this.showClear = true
    }
  },
  beforeUnmount () {
    document.body.classList.remove('dark')
  },
  methods: {
    ...mapActions(['setSidebar']),
    toggle () {
      this.collapsed = !this.collapsed
      this.setSidebar(!this.collapsed)
      triggerWindowResizeEvent()
    },
    paddingCalc () {
      let left = ''
      if (this.sidebarOpened) {
        left = this.isDesktop() ? '256px' : '80px'
      } else {
        left = this.isMobile() ? '0' : (this.fixSidebar ? '80px' : '0')
      }
      return left
    },
    menuSelect () {
      if (!this.isDesktop()) {
        this.collapsed = false
      }
    },
    toggleSetting (showSetting) {
      this.showSetting = showSetting
    },
    onClearNotification () {
      this.$notification.destroy()
      this.$store.commit('SET_COUNT_NOTIFY', 0)
    },
    checkShutdown () {
      api('readyForShutdown', {}).then(json => {
        this.$store.dispatch('SetShutdownTriggered', json.readyforshutdownresponse.readyforshutdown.shutdowntriggered || false)
      })
    }
  }
}
</script>

<style lang="less">
.layout-content {
  &.is-header-fixed {
    margin: 78px 12px 0;
  }
}

// Todo try to get this rules scoped
.ant-drawer.drawer-sider {
  .sider {
    box-shadow: none;
  }

  &.dark {
    .ant-drawer-content {
      background-color: rgb(0, 21, 41);
      max-width: 256px;
    }

    .ant-drawer-content-wrapper {
      width: 256px !important;;
    }
  }

  &.light {
    box-shadow: none;

    .ant-drawer-content {
      background-color: #fff;
      max-width: 256px;
    }

    .ant-drawer-content-wrapper {
      width: 256px !important;
    }
  }

  .ant-drawer-body {
    padding: 0;
  }
}

.shutdownHeader {
  font-weight: bold;
  height: 25px;
  text-align: center;
  padding: 0px;
  margin: 0px;
  width: 100vw;
  position: absolute;
}

</style>
